package reflectdemo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, NoSuchFieldException {
        /*//获取Class对象
        Class<?> c= Class.forName("reflectdemo.Student");
        //通过反射获取实例化对象
        Student stu = (Student) c.newInstance();
        System.out.println(stu);*/
        reflectPrivateConstructor();
        System.out.println("============");
        reflectPrivateField();
        System.out.println("============");
        reflectPrivateMethod();
    }

    // 1.反射私有的构造方法
    public static void reflectPrivateConstructor() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<?> c = Class.forName("reflectdemo.Student");//获取Class对象
        //获得该类中与参数类型匹配的构造方法
        Constructor<Student> con =
                (Constructor) c.getDeclaredConstructor(String.class, int.class);//参数为私有构造方法的参数类型.class
        con.setAccessible(true); //设置为可修改

        Student s = (Student) con.newInstance("lisi",20);
        System.out.println(s);
    }


    //2.反射私有属性
    public static void reflectPrivateField() throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
        Class<?> c = Class.forName("reflectdemo.Student");//获取Class对象

        Field field =c.getDeclaredField("name");  //参数填写私有属性变量名
        field.setAccessible(true);//设置可修改
        Student stu = (Student) c.newInstance();

        field.set(stu,"王五");//更该私有属性

        System.out.println(stu);
    }

    //3.//2.反射私有方法
    public static void reflectPrivateMethod() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        Class<?> c = Class.forName("reflectdemo.Student");//获取Class对象

        Method method = c.getDeclaredMethod("function", String.class);  //参数为方法名和该方法的参数类型
        method.setAccessible(true); //设置可修改

        Student stu = (Student) c.newInstance();

        method.invoke(stu,"我试一试哦");  //调用该方法，第二个参数为调用方法的参数
    }
}
